/*
 * Workspace base class
 *
 * popup login window when auth fails (call onLogin handler)
 * update (re-login) ticket every 15 minutes
 *
 */

Ext.define('PVE.Workspace', {
    extend: 'Ext.container.Viewport',

    title: 'Proxmox Virtual Environment',

    loginData: null, // Data from last login call

    onLogin: function (loginData) {
        // override me
    },

    // private
    updateLoginData: function (loginData) {
        let me = this;
        me.loginData = loginData;
        Proxmox.Utils.setAuthData(loginData);

        let rt = me.down('pveResourceTree');
        rt.setDatacenterText(loginData.clustername);
        PVE.ClusterName = loginData.clustername;

        if (loginData.cap) {
            Ext.state.Manager.set('GuiCap', loginData.cap);
        }
        me.response401count = 0;

        me.onLogin(loginData);
    },

    // private
    showLogin: function () {
        let me = this;

        Proxmox.Utils.authClear();
        Ext.state.Manager.clear('GuiCap');
        Proxmox.UserName = null;
        me.loginData = null;

        if (!me.login) {
            me.login = Ext.create('PVE.window.LoginWindow', {
                handler: function (data) {
                    me.login = null;
                    me.updateLoginData(data);
                    Proxmox.Utils.checked_command(Ext.emptyFn); // display subscription status
                },
            });
        }
        me.onLogin(null);
        me.login.show();
    },

    initComponent: function () {
        let me = this;

        Ext.tip.QuickTipManager.init();

        // fixme: what about other errors
        Ext.Ajax.on('requestexception', function (conn, response, options) {
            if (
                (response.status === 401 || response.status === '401') &&
                !PVE.Utils.silenceAuthFailures
            ) {
                // auth failure
                // don't immediately show as logged out to cope better with some big
                // upgrades, which may temporarily produce a false positive 401 err
                me.response401count++;
                if (me.response401count > 5) {
                    me.showLogin();
                }
            }
        });

        me.callParent();

        if (!Proxmox.Utils.authOK()) {
            me.showLogin();
        } else if (me.loginData) {
            me.onLogin(me.loginData);
        }

        Ext.TaskManager.start({
            run: function () {
                let ticket = Proxmox.Utils.authOK();
                if (!ticket || !Proxmox.UserName) {
                    return;
                }

                Ext.Ajax.request({
                    params: {
                        username: Proxmox.UserName,
                        password: ticket,
                    },
                    url: '/api2/json/access/ticket',
                    method: 'POST',
                    success: function (response, opts) {
                        let obj = Ext.decode(response.responseText);
                        me.updateLoginData(obj.data);
                    },
                });
            },
            interval: 15 * 60 * 1000,
        });
    },
});

Ext.define('PVE.StdWorkspace', {
    extend: 'PVE.Workspace',

    alias: ['widget.pveStdWorkspace'],

    // private
    setContent: function (comp) {
        let me = this;

        let view = me.child('#content');
        let layout = view.getLayout();
        let current = layout.getActiveItem();

        if (comp) {
            Proxmox.Utils.setErrorMask(view, false);
            comp.border = false;
            view.add(comp);
            if (current !== null && layout.getNext()) {
                layout.next();
                let task = Ext.create('Ext.util.DelayedTask', function () {
                    view.remove(current);
                });
                task.delay(10);
            }
        } else {
            view.removeAll(); // helper for cleaning the content when logging out
        }
    },

    selectById: function (nodeid) {
        let me = this;
        me.down('pveResourceTree').selectById(nodeid);
    },

    onLogin: function (loginData) {
        let me = this;

        me.updateUserInfo();

        if (loginData) {
            PVE.data.ResourceStore.startUpdate();

            Proxmox.Utils.API2Request({
                url: '/version',
                method: 'GET',
                success: function (response) {
                    PVE.VersionInfo = response.result.data;
                    me.updateVersionInfo();
                },
            });

            PVE.UIOptions.update();

            Proxmox.Utils.API2Request({
                url: '/cluster/sdn',
                method: 'GET',
                success: function (response) {
                    PVE.SDNInfo = response.result.data;
                },
                failure: function (response) {
                    PVE.SDNInfo = null;
                    let ui = Ext.ComponentQuery.query('treelistitem[text="SDN"]')[0];
                    if (ui) {
                        ui.addCls('x-hidden-display');
                    }
                },
            });

            Proxmox.Utils.API2Request({
                url: '/access/domains',
                method: 'GET',
                success: function (response) {
                    let [_username, realm] = Proxmox.Utils.parse_userid(Proxmox.UserName);
                    response.result.data.forEach((domain) => {
                        if (domain.realm === realm) {
                            let schema = PVE.Utils.authSchema[domain.type];
                            if (schema) {
                                me.query('#tfaitem')[0].setHidden(!schema.tfa);
                                me.query('#passworditem')[0].setHidden(!schema.pwchange);
                            }
                        }
                    });
                },
            });
        }
    },

    updateUserInfo: function () {
        let me = this;
        let ui = me.query('#userinfo')[0];
        ui.setText(Ext.String.htmlEncode(Proxmox.UserName || ''));
        ui.updateLayout();
    },

    updateVersionInfo: function () {
        let me = this;

        let ui = me.query('#versioninfo')[0];

        if (PVE.VersionInfo) {
            let version = PVE.VersionInfo.version;
            ui.update('Virtual Environment ' + version);
        } else {
            ui.update('Virtual Environment');
        }
        ui.updateLayout();
    },

    initComponent: function () {
        let me = this;

        Ext.History.init();

        let appState = Ext.create('PVE.StateProvider');
        Ext.state.Manager.setProvider(appState);

        let selview = Ext.create('PVE.form.ViewSelector', {
            flex: 1,
            padding: '0 5 0 0',
        });

        let rtree = Ext.createWidget('pveResourceTree', {
            viewFilter: selview.getViewFilter(),
            flex: 1,
            selModel: {
                selType: 'treemodel',
                listeners: {
                    selectionchange: function (sm, selected) {
                        if (selected.length <= 0) {
                            return;
                        }
                        let treeNode = selected[0];
                        let treeTypeToClass = {
                            root: 'PVE.dc.Config',
                            node: 'PVE.node.Config',
                            qemu: 'PVE.qemu.Config',
                            lxc: 'pveLXCConfig',
                            storage: 'PVE.storage.Browser',
                            sdn: 'PVE.sdn.Browser',
                            pool: 'pvePoolConfig',
                            tag: 'pveTagConfig',
                        };
                        PVE.curSelectedNode = treeNode;
                        me.setContent({
                            xtype:
                                treeTypeToClass[treeNode.data.type || 'root'] || 'pvePanelConfig',
                            showSearch:
                                treeNode.data.id === 'root' ||
                                Ext.isDefined(treeNode.data.groupbyid),
                            pveSelNode: treeNode,
                            workspace: me,
                            viewFilter: selview.getViewFilter(),
                        });
                    },
                },
            },
        });

        selview.on('select', function (combo, records) {
            if (records) {
                let view = combo.getViewFilter();
                rtree.setViewFilter(view);
            }
        });

        let caps = appState.get('GuiCap');

        let createVM = Ext.createWidget('button', {
            pack: 'end',
            margin: '3 5 0 0',
            baseCls: 'x-btn',
            iconCls: 'fa fa-desktop',
            text: gettext('Create VM'),
            disabled: !caps.vms['VM.Allocate'],
            handler: function () {
                let wiz = Ext.create('PVE.qemu.CreateWizard', {});
                wiz.show();
            },
        });

        let createCT = Ext.createWidget('button', {
            pack: 'end',
            margin: '3 5 0 0',
            baseCls: 'x-btn',
            iconCls: 'fa fa-cube',
            text: gettext('Create CT'),
            disabled: !caps.vms['VM.Allocate'],
            handler: function () {
                let wiz = Ext.create('PVE.lxc.CreateWizard', {});
                wiz.show();
            },
        });

        appState.on('statechange', function (sp, key, value) {
            if (key === 'GuiCap' && value) {
                caps = value;
                createVM.setDisabled(!caps.vms['VM.Allocate']);
                createCT.setDisabled(!caps.vms['VM.Allocate']);
            } else if (key === '_stripBeta') {
                let betaLink = me.query('#betalink')?.[0];
                if (betaLink) {
                    betaLink.setHidden(true);
                }

                const indexOfTilde = PVE.VersionInfo?.version.indexOf('~') ?? '';
                if (indexOfTilde !== -1) {
                    PVE.VersionInfo.version = PVE.VersionInfo.version.substring(0, indexOfTilde);
                    me.updateVersionInfo();
                }
            }
        });

        Ext.apply(me, {
            layout: { type: 'border' },
            border: false,
            items: [
                {
                    region: 'north',
                    title: gettext('Header'), // for ARIA
                    header: false, // avoid rendering the title
                    layout: {
                        type: 'hbox',
                        align: 'middle',
                    },
                    baseCls: 'x-plain',
                    defaults: {
                        baseCls: 'x-plain',
                    },
                    border: false,
                    margin: '2 0 2 5',
                    items: [
                        {
                            xtype: 'proxmoxlogo',
                        },
                        {
                            minWidth: 150,
                            id: 'versioninfo',
                            html: 'Virtual Environment',
                            style: {
                                'font-size': '14px',
                                'line-height': '18px',
                            },
                        },
                        {
                            xtype: 'pveGlobalSearchField',
                            tree: rtree,
                        },
                        {
                            flex: 1,
                        },
                        {
                            xtype: 'proxmoxHelpButton',
                            hidden: false,
                            baseCls: 'x-btn',
                            iconCls: 'fa fa-book x-btn-icon-el-default-toolbar-small ',
                            listenToGlobalEvent: false,
                            onlineHelp: 'pve_documentation_index',
                            text: gettext('Documentation'),
                            margin: '0 5 0 0',
                        },
                        createVM,
                        createCT,
                        {
                            pack: 'end',
                            margin: '0 5 0 0',
                            id: 'userinfo',
                            xtype: 'button',
                            baseCls: 'x-btn',
                            style: {
                                // proxmox dark grey p light grey as border
                                backgroundColor: '#464d4d',
                                borderColor: '#ABBABA',
                            },
                            iconCls: 'fa fa-user',
                            menu: [
                                {
                                    iconCls: 'fa fa-gear',
                                    text: gettext('My Settings'),
                                    handler: function () {
                                        var win = Ext.create('PVE.window.Settings');
                                        win.show();
                                    },
                                },
                                {
                                    text: gettext('Password'),
                                    itemId: 'passworditem',
                                    iconCls: 'fa fa-fw fa-key',
                                    handler: function () {
                                        var win = Ext.create('Proxmox.window.PasswordEdit', {
                                            userid: Proxmox.UserName,
                                            confirmCurrentPassword: Proxmox.UserName !== 'root@pam',
                                            minLength: 8,
                                        });
                                        win.show();
                                    },
                                },
                                {
                                    text: 'TFA',
                                    itemId: 'tfaitem',
                                    iconCls: 'fa fa-fw fa-lock',
                                    handler: function (btn, event, rec) {
                                        Ext.state.Manager.getProvider().set(
                                            'dctab',
                                            { value: 'tfa' },
                                            true,
                                        );
                                        me.selectById('root');
                                    },
                                },
                                {
                                    iconCls: 'fa fa-paint-brush',
                                    text: gettext('Color Theme'),
                                    handler: function () {
                                        Ext.create('Proxmox.window.ThemeEditWindow').show();
                                    },
                                },
                                {
                                    iconCls: 'fa fa-language',
                                    text: gettext('Language'),
                                    handler: function () {
                                        Ext.create('Proxmox.window.LanguageEditWindow').show();
                                    },
                                },
                                '-',
                                {
                                    iconCls: 'fa fa-fw fa-sign-out',
                                    text: gettext('Logout'),
                                    handler: function () {
                                        PVE.data.ResourceStore.loadData([], false);
                                        me.showLogin();
                                        me.setContent(null);
                                        var rt = me.down('pveResourceTree');
                                        rt.setDatacenterText(undefined);
                                        rt.clearTree();

                                        // empty the stores of the StatusPanel child items
                                        var statusPanels =
                                            Ext.ComponentQuery.query('pveStatusPanel grid');
                                        Ext.Array.forEach(statusPanels, function (comp) {
                                            if (comp.getStore()) {
                                                comp.getStore().loadData([], false);
                                            }
                                        });
                                    },
                                },
                            ],
                        },
                    ],
                },
                {
                    region: 'center',
                    stateful: true,
                    stateId: 'pvecenter',
                    minWidth: 100,
                    minHeight: 100,
                    id: 'content',
                    xtype: 'container',
                    layout: { type: 'card' },
                    border: false,
                    margin: '0 5 0 0',
                    items: [],
                },
                {
                    region: 'west',
                    stateful: true,
                    stateId: 'pvewest',
                    itemId: 'west',
                    xtype: 'container',
                    border: false,
                    layout: { type: 'vbox', align: 'stretch' },
                    margin: '0 0 0 5',
                    split: true,
                    width: 300,
                    items: [
                        {
                            xtype: 'container',
                            layout: 'hbox',
                            padding: '0 0 5 0',
                            items: [
                                selview,
                                {
                                    xtype: 'button',
                                    cls: 'x-btn-default-toolbar-small',
                                    iconCls: 'fa fa-fw fa-gear x-btn-icon-el-default-toolbar-small',
                                    handler: () => {
                                        Ext.create('PVE.window.TreeSettingsEdit', {
                                            autoShow: true,
                                            apiCallDone: () => PVE.UIOptions.fireUIConfigChanged(),
                                        });
                                    },
                                },
                            ],
                        },
                        rtree,
                    ],
                    listeners: {
                        resize: function (panel, width, height) {
                            var viewWidth = me.getSize().width;
                            if (width > viewWidth - 100 && viewWidth > 150) {
                                panel.setWidth(viewWidth - 100);
                            }
                        },
                    },
                },
                {
                    xtype: 'pveStatusPanel',
                    stateful: true,
                    stateId: 'pvesouth',
                    itemId: 'south',
                    region: 'south',
                    margin: '0 5 5 5',
                    title: gettext('Logs'),
                    collapsible: true,
                    header: false,
                    height: 200,
                    split: true,
                    listeners: {
                        resize: function (panel, width, height) {
                            var viewHeight = me.getSize().height;
                            if (height > viewHeight - 150 && viewHeight > 200) {
                                panel.setHeight(viewHeight - 150);
                            }
                        },
                    },
                },
            ],
        });

        me.callParent();

        me.updateUserInfo();

        // on resize, center all modal windows
        Ext.on('resize', function () {
            let modalWindows = Ext.ComponentQuery.query('window[modal]');
            if (modalWindows.length > 0) {
                modalWindows.forEach((win) => win.alignTo(me, 'c-c'));
            }
        });

        let tagSelectors = [];
        ['circle', 'dense'].forEach((style) => {
            ['dark', 'light'].forEach((variant) => {
                let selector = `.proxmox-tags-${style} :not(.proxmox-tags-full) > .proxmox-tag-${variant}`;
                tagSelectors.push(selector);
            });
        });

        Ext.create('Ext.tip.ToolTip', {
            target: me.el,
            delegate: tagSelectors.join(', '),
            trackMouse: true,
            renderTo: Ext.getBody(),
            border: 0,
            minWidth: 0,
            padding: 0,
            bodyBorder: 0,
            bodyPadding: 0,
            dismissDelay: 0,
            userCls: 'pmx-tag-tooltip',
            shadow: false,
            listeners: {
                beforeshow: function (tip) {
                    let tag = Ext.htmlEncode(tip.triggerElement.innerHTML);
                    let tagEl = Proxmox.Utils.getTagElement(tag, PVE.UIOptions.tagOverrides);
                    tip.update(`<span class="proxmox-tags-full">${tagEl}</span>`);
                },
            },
        });
    },
});
